package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.autoconfig.AipFaceTemplate;
import com.itheima.autoconfig.HuanXinTemplate;
import com.itheima.autoconfig.OssTemplate;
import com.itheima.autoconfig.SmsTemplate;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.vo.ErrorResult;
import com.itheima.domain.vo.UserInfoVo;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.db.UserService;
import com.itheima.service.mongo.UserLocationService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.checkerframework.checker.units.qual.A;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author 请不要叫我高司令
 * @Date 2022/3/13 21:28
 * @Version 1.0
 */

@Component
public class UserManager {

    @DubboReference
    private UserService userService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    private SmsTemplate smsTemplate;


    @DubboReference
    private UserInfoService userInfoService;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private AipFaceTemplate aipFaceTemplate;


    @DubboReference
    private UserLocationService userLocationService;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    // 保存用户
    public ResponseEntity save(User user) {
        Long userId = userService.save(user);
        return ResponseEntity.ok(userId); // 状态码200，响应体数据 101 用户id
    }

    // 查询用户
    public ResponseEntity findByPhone(String phone) {
        User user = userService.findByPhone(phone);
        return ResponseEntity.ok(user);// 状态码200，响应体数据 {xxx:xxx} 用户对象
    }


    //发送验证码
    public void sendSms(String phone) {

        //1.生成验证码
        String smsCode = RandomUtil.randomNumbers(6);
        smsCode = "123456";

        //调用阿里云发送短信
        //smsTemplate.sendSms(phone, smsCode);//TODO 以后再改

        //3.redis存验证码,存五分钟
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE + phone, smsCode, Duration.ofMinutes(5));

    }

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    // 注册、登录
    public ResponseEntity loginVerification(String phone, String verificationCode) {

        //1.取出验证码
        String redisCode = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE + phone);

        //2.比对验证码
        if (!StrUtil.equals(verificationCode, redisCode)) {

            return ResponseEntity.status(500).body(ErrorResult.loginError());

        }
        //3.根据手机号查询用户
        User user = userService.findByPhone(phone);

        //判断是不是新用户
        Boolean isNew;

        String type = null;
        if (ObjectUtil.isNotEmpty(user)) {//老用户
            isNew = false;
            type = "0101";
        } else {
            isNew = true; //新用户

            user = new User();
            user.setMobile(phone);
            user.setPassword(ConstantUtil.INIT_PASSWORD);
            //rpc远程保存
            Long userId = userService.save(user);
            //设置信用的userId
            user.setId(userId);

            //注册环信用户
            huanXinTemplate.register("HX" + userId);

            type = "0102";



        }
        //4.制作令牌
        //密码先去除
        user.setPassword(null);
        Map<String, Object> claims = BeanUtil.beanToMap(user);
        String token = JwtUtil.createToken(claims);

        //5.redis存储 有效期7天
        String json = JSON.toJSONString(user);
        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, json, Duration.ofDays(7));

        //redis验证码作废
        stringRedisTemplate.delete(ConstantUtil.SMS_CODE + phone);

        //------------------
        //封装log对象
        Log log = new Log();
        log.setUserId(user.getId());
        log.setLogTime(DateUtil.formatDate(new Date()));
        //用户登录地点
        log.setPlace(userLocationService.findLocation(user.getId()));
        log.setEquipment("华为p50");
        log.setType(type);

        //发送mq日志消息
        rabbitTemplate.convertAndSend("tanhua.log", log);
        //------------------



        //6.返回结果
        Map resultMap = new HashMap();
        resultMap.put("token", token);
        resultMap.put("isNew", isNew);

        return ResponseEntity.ok(resultMap);


    }


    // 完善用户信息
    public ResponseEntity loginReginfo(UserInfo userInfo, String token) {

        User user = findUserByToken(token);
        if (ObjectUtil.isEmpty(user)) {
            return ResponseEntity.status(500).body(ErrorResult.loginError());
        }

        //用户id存到userInfo
        userInfo.setId(user.getId());

        //调用rpc保存
        userInfoService.save(userInfo);

        return ResponseEntity.ok(null);

    }

    // 完善用户信息
    public User findUserByToken(String token) {

        // 检测redis中是否有token
        Boolean isCheck = stringRedisTemplate.hasKey(ConstantUtil.USER_TOKEN + token);
        if (isCheck == true) {

            //从redis中取user
            String json = stringRedisTemplate.opsForValue().get(ConstantUtil.USER_TOKEN + token);
            User user = JSON.parseObject(json, User.class);

            //续期7天
            stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, json, Duration.ofDays(7));

            //返回user对象
            return user;

        }
        //未登录
        return null;

    }

    // 完善头像信息
    public ResponseEntity loginReginfoHead(MultipartFile headPhoto, String token) throws IOException {

        //1.人脸检测
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        //不是人脸
        if (detect == false) {
            return ResponseEntity.status(500).body(ErrorResult.faceError());

        }

        //2.oss人像上传
        String picUrl = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());

        //3.解析token获取user
        User user = findUserByToken(token);

        //4.封装userInfo
        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());
        userInfo.setAvatar(picUrl);
        userInfo.setCoverPic(picUrl);

        //5.调用rpc更新
        userInfoService.update(userInfo);
        return ResponseEntity.ok(null);
    }

    // 查询用户基本信息
    public ResponseEntity findUserInfoVo(Long userID) {
        // 1.查询userInfo

        UserInfo userInfo = userInfoService.findById(userID);
        //2.封装vo
        UserInfoVo vo = new UserInfoVo();

        BeanUtil.copyProperties(userInfo, vo);//userInfo属性批量复制到vo中(类型不同会强转)
        return ResponseEntity.ok(vo);
    }

    // 更新用户基本信息
    public void putUserInfo(UserInfo userInfo) {

        // 调用rpc更新
        userInfoService.update(userInfo);

    }
}













































